package conf2;

import conf2.model.EActor;
import conf2.model.EActor.Side;
import conf2.model.ETerritory;
import conf2.model.WorldState;
import conf2.ui.GamePiece;
import conf2.ui.PieceCollection;
import conf2.ui.RegionBounds;
import java.awt.Point;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PiecePositioner {

    private static boolean shuffleDark = false,  shuffleLight = false;

    public static void setShufflePiecesForSide(Side side, boolean doShuffle) {
        if (side == Side.LIGHT) {
            shuffleLight = doShuffle;
        } else if (side == Side.DARK) {
            shuffleDark = doShuffle;
        }
    }

    public static void orderAll(PieceCollection coll, WorldState ws) {
        for (ETerritory et : ETerritory.values()) {
            if (!ws.isEmpty(et)) {
                orderIn(et, coll, ws);
            }
        }
    }

    public static void orderIn(ETerritory et, PieceCollection coll, WorldState ws) {
        List<EActor> actors = ws.getOccupants(et);

        Point center = RegionBounds.getCenterPoint(et);
        final int GAP = 2;

        boolean isMyHome = false, isOpponentHome = false;

        // Hack!!
        if (et == ETerritory.MORDOR || et == ETerritory.SHIRE) {
            Point mordorCenter = RegionBounds.getCenterPoint(ETerritory.MORDOR);
            Point shireCenter = RegionBounds.getCenterPoint(ETerritory.SHIRE);
            if (shireCenter.y > mordorCenter.y) {
                isMyHome = et == ETerritory.SHIRE;
                isOpponentHome = et == ETerritory.MORDOR;
            } else {
                isMyHome = et == ETerritory.MORDOR;
                isOpponentHome = et == ETerritory.SHIRE;
            }
        }

        boolean checkShuffle = true;
        switch (actors.size()) {
            case 0:
                checkShuffle = false;
                // Whatever
                break;
            case 1: {
                GamePiece a = coll.get(actors.get(0));
                a.setLocation(center.x - a.getWidth() / 2,
                        center.y - a.getHeight() / 2);
                a.remember();
                break;
            }
            case 2: {
                GamePiece aLeft = coll.get(actors.get(0));
                GamePiece aRight = coll.get(actors.get(1));
                aLeft.setLocation(center.x - aLeft.getWidth() - GAP,
                        center.y - aLeft.getHeight() / 2);
                aRight.setLocation(center.x + GAP,
                        center.y - aRight.getHeight() / 2);
                aLeft.remember();
                aRight.remember();
                break;

            }
            case 3: {
                GamePiece aSingle = coll.get(actors.get(2));
                GamePiece aLeft = coll.get(actors.get(0));
                GamePiece aRight = coll.get(actors.get(1));
                if (isOpponentHome) {
                    aSingle.setLocation(center.x - aSingle.getWidth() / 2,
                            center.y - aSingle.getHeight() - 2 * GAP);
                    aLeft.setLocation(center.x - aLeft.getWidth() - GAP,
                            center.y + GAP);
                    aRight.setLocation(center.x + GAP,
                            center.y + GAP);
                    aSingle.remember();
                    aLeft.remember();
                    aRight.remember();
                } else if (isMyHome) {
                    aSingle.setLocation(center.x - aSingle.getWidth() / 2,
                            center.y + GAP);
                    aLeft.setLocation(center.x - aLeft.getWidth() - GAP,
                            center.y - aLeft.getHeight());
                    aRight.setLocation(center.x + GAP,
                            center.y - aLeft.getHeight());
                    aSingle.remember();
                    aLeft.remember();
                    aRight.remember();
                } else {
                    Logger.getLogger(PiecePositioner.class.getName()).log(
                            Level.SEVERE, "Serious fuckup! 3 pieces in non-home territory!");
                }
                break;
            }

            case 4: {
                GamePiece left = coll.get(actors.get(0));
                GamePiece top = coll.get(actors.get(1));
                GamePiece right = coll.get(actors.get(2));
                GamePiece bottom = coll.get(actors.get(3));

                if (isOpponentHome) {
                    bottom.setLocation(center.x - GamePiece.PIECE_WIDTH / 2,
                            center.y - GamePiece.PIECE_HEIGHT - 2 * GAP);
                    left.setLocation(center.x - (int) (1.5 * GamePiece.PIECE_WIDTH) - GAP,
                            center.y + GAP);
                    top.setLocation(center.x - GamePiece.PIECE_WIDTH / 2,
                            center.y + GAP);
                    right.setLocation(center.x + (int) GamePiece.PIECE_WIDTH / 2 + GAP,
                            center.y + GAP);

                } else if (isMyHome) {
                    bottom.setLocation(center.x - GamePiece.PIECE_WIDTH / 2,
                            center.y + 2 * GAP);
                    left.setLocation(center.x - (int) (1.5 * GamePiece.PIECE_WIDTH) - GAP,
                            center.y - GamePiece.PIECE_HEIGHT - GAP);
                    top.setLocation(center.x - GamePiece.PIECE_WIDTH / 2,
                            center.y - GamePiece.PIECE_HEIGHT - GAP);
                    right.setLocation(center.x + GamePiece.PIECE_WIDTH / 2 + GAP,
                            center.y - GamePiece.PIECE_HEIGHT - GAP);

                } else {
                    Logger.getLogger(PiecePositioner.class.getName()).log(
                            Level.SEVERE, "Serious fuckup! 4 pieces in non-home territory!");
                }

                left.remember();
                right.remember();
                top.remember();
                bottom.remember();

                break;
            }

            default:
                Logger.getLogger(PiecePositioner.class.getName()).log(
                        Level.SEVERE, "Serious fuckup! Wrong number of actors! " + actors.size());
        }

        if (checkShuffle) {
            Side pieceSide = actors.get(0).getSide();
            if ((pieceSide == Side.LIGHT && shuffleLight) ||
                    (pieceSide == Side.DARK && shuffleDark)) {
                shufflePiecesIn(et, coll, ws);
            }
        }
    }

    private static void shufflePiecesIn(ETerritory et, PieceCollection coll, WorldState ws) {
        final int COUNT = ws.getOccupantCount(et);

        Point[] locations = new Point[COUNT];
        GamePiece[] pieces = new GamePiece[COUNT];

        // Assign
        int i = 0;
        for (EActor ea : ws.getOccupants(et)) {
            pieces[i] = coll.get(ea);
            locations[i] = pieces[i].getLocation();
            i++;
        }

        // Shuffle
        for (int a = 0; a < COUNT - 1; a++) {
            int b = (int) (Math.random() * COUNT);
            Point p = locations[a];
            locations[a] = locations[b];
            locations[b] = p;
        }

        // Reassign
        for (i = 0; i < COUNT; i++) {
            pieces[i].setLocation(locations[i]);
        }

    }
}
